home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ABUSESRC.ZIP
/
AbuseSrc
/
abuse
/
src
/
old_earth_menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-11
|
18KB
|
703 lines
#include "menu.hpp"
#include "lisp.hpp"
#include "loader.hpp"
#include "game.hpp"
#include "timing.hpp"
#include "game.hpp"
#include "id.hpp"
#include "pmenu.hpp"
#include "gui.hpp"
#include "property.hpp"
#include "dev.hpp"
#include "clisp.hpp"
#include "gamma.hpp"
#include "dprint.hpp"
#include "demo.hpp"
#include <math.h>
jwindow *volume_window=NULL;
//percent is 0..256
void tint_area(int x1, int y1, int x2, int y2, int r_to, int g_to, int b_to, int percent)
{
int x,y;
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
if (x1<cx1) x1=cx1;
if (y1<cy1) y1=cy1;
if (x2>cx2) x2=cx2;
if (y2>cy2) y2=cy2;
if (x2<x1 || y2<y1) return ;
percent=256-percent;
for (y=y1;y<=y2;y++)
{
unsigned char *sl=screen->scan_line(y)+x1;
for (x=x1;x<=x2;x++,sl++)
{
unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3;
unsigned char r=((*(paddr++))-r_to)*percent/256+r_to;
unsigned char g=((*(paddr++))-g_to)*percent/256+g_to;
unsigned char b=((*(paddr++))-b_to)*percent/256+b_to;
*sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3);
}
}
screen->add_dirty(x1,y1,x2,y2);
}
void darken_area(int x1, int y1, int x2, int y2, int amount)
{
int x,y;
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
if (x1<cx1) x1=cx1;
if (y1<cy1) y1=cy1;
if (x2>cx2) x2=cx2;
if (y2>cy2) y2=cy2;
if (x2<x1 || y2<y1) return ;
for (y=y1;y<=y2;y++)
{
unsigned char *sl=screen->scan_line(y)+x1;
for (x=x1;x<=x2;x++,sl++)
{
unsigned char *paddr=(unsigned char *)pal->addr()+(*sl)*3;
unsigned char r=(*(paddr++))*amount/256;
unsigned char g=(*(paddr++))*amount/256;
unsigned char b=(*(paddr++))*amount/256;
*sl=color_table->lookup_color((r)>>3,(g)>>3,(b)>>3);
}
}
screen->add_dirty(x1,y1,x2,y2);
}
void dark_wiget(int x1, int y1, int x2, int y2, int br, int dr, int amount)
{
screen->add_dirty(x1,y1,x2,y2);
screen->line(x1,y1,x1,y2,br);
screen->line(x1+1,y1,x2,y1,br);
screen->line(x2,y1+1,x2,y2,dr);
screen->line(x1+1,y2,x2,y2,dr);
darken_area(x1+1,y1+1,x2-1,y2-1,amount);
}
char *men_str(void *arg)
{
switch (item_type(arg))
{
case L_STRING :
{ return lstring_value(arg); } break;
case L_CONS_CELL :
{ return lstring_value(CAR(arg)); } break;
default :
{
lprint(arg);
printf(" is not a valid menu option\n");
exit(0);
}
}
return NULL;
}
void main_menu();
int menu(void *args, JCFont *font) // reurns -1 on esc
{
main_menu();
char *title=NULL;
if (!NILP(CAR(args)))
title=lstring_value(CAR(args));
Cell *def=lcar(lcdr(lcdr(args)));
args=CAR(CDR(args));
int options=list_length(args);
int mh=(font->height()+1)*options+10,maxw=0;
Cell *c=(Cell *)args;
for (;!NILP(c);c=CDR(c))
{
if (strlen(men_str(CAR(c)))>maxw)
maxw=strlen(men_str(CAR(c)));
}
int mw=(font->width())*maxw+20;
int mx=screen->width()/2-mw/2,
my=screen->height()/2-mh/2;
screen->add_dirty(mx,my,mx+mw-1,my+mh-1);
if (title)
{
int tl=strlen(title)*font->width();
int tx=screen->width()/2-tl/2;
dark_wiget(tx-2,my-font->height()-4,tx+tl+2,my-2,eh->medium_color(),eh->dark_color(),180);
font->put_string(screen,tx+1,my-font->height()-2,title,eh->bright_color());
}
dark_wiget(mx,my,mx+mw-1,my+mh-1,eh->medium_color(),eh->dark_color(),200);
int y=my+5;
for (c=(Cell *)args;!NILP(c);c=CDR(c))
{
char *ms=men_str(CAR(c));
font->put_string(screen,mx+10+1,y+1,ms,eh->black());
font->put_string(screen,mx+10,y,ms,eh->bright_color());
y+=font->height()+1;
}
eh->flush_screen();
event ev;
int choice=0,done=0;
int bh=font->height()+3;
image *save=new image(mw-2,bh);
int color=128,cdir=50;
time_marker *last_color_time=NULL;
if (!NILP(def))
choice=lnumber_value(def);
do
{
if (eh->event_waiting())
{
eh->get_event(ev);
if (ev.type==EV_KEY)
{
switch (ev.key)
{
case JK_ESC :
{ choice=-1; done=1; } break;
case JK_ENTER :
{ done=1; } break;
case JK_DOWN :
{ if (choice<options-1)
choice++;
else choice=0;
} break;
case JK_UP :
{
if (choice>0)
choice--;
else choice=options-1;
} break;
}
} else if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
{
if (ev.mouse_move.x>mx && ev.mouse_move.x<mx+mw && ev.mouse_move.y>my &&
ev.mouse_move.y<my+mh)
{
int msel=(ev.mouse_move.y-my)/(font->height()+1);
if (msel>=options) msel=options-1;
if (msel==choice) // clicked on already selected item, return it
done=1;
else choice=msel; // selects an item
}
}
eh->flush_screen();
}
time_marker cur_time;
if (!last_color_time || (int)(cur_time.diff_time(last_color_time)*1000)>120)
{
if (last_color_time)
delete last_color_time;
last_color_time=new time_marker;
int by1=(font->height()+1)*choice+my+5-2;
int by2=by1+bh-1;
screen->put_part(save,0,0,mx+1,by1,mx+mw-2,by2);
tint_area(mx+1,by1,mx+mw-2,by2,63,63,63,color);
char *cur=men_str(nth(choice,args));
font->put_string(screen,mx+10+1,by1+3,cur,eh->black());
font->put_string(screen,mx+10,by1+2,cur,eh->bright_color());
screen->rectangle(mx+1,by1,mx+mw-2,by2,eh->bright_color());
color+=cdir;
if (color<12 || color>256)
{
cdir=-cdir;
color+=cdir;
}
eh->flush_screen();
save->put_image(screen,mx+1,by1);
} else milli_wait(10);
} while (!done);
if (last_color_time)
delete last_color_time;
delete save;
the_game->draw(the_game->state==SCENE_STATE);
if (choice!=-1)
{
void *val=nth(choice,args);
if (item_type(val)==L_CONS_CELL) // is there another value that the user want us to return?
return lnumber_value(lcdr(val));
}
return choice;
}
struct mask_line
{
int x,size;
ushort *remap;
} ;
void scan_map(image *screen, int sx, int sy, image *im, image *clouds, mask_line *p, int mask_height,
int xoff, int coff)
{
int x1=10000,x2=0;
int iw=im->width();
ushort r,co,off,cc;
int y=0;
for (;y<mask_height;y++)
{
mask_line *n=p+y;
uchar *sl=screen->scan_line(y+sy)+sx+n->x;
uchar *sl2=im->scan_line(y);
// uchar *sl3=clouds->scan_line(y);
ushort *rem=n->remap;
if (sx+n->x<x1) x1=sx+n->x;
int x=0;
for (;x<n->size;x++,sl++,rem++)
{
r=*rem;
// co=(r+coff);
// if (co>=iw) co-=iw;
// cc=sl3[co];
off=(r+xoff);
if (off>=iw) off-=iw;
// if (cc)
// *sl=*(white_light+(r/4+(x+y)%2)*256+*(white_light+((256-cc)/2-64)*256+sl2[off]));
// *sl=*(white_light+(r/4+(x+y)%2)*256+*(white_light+(48+cc/16)*256+sl2[off]));
// else
*sl=*(white_light+(r/4+(x+y)%2)*256+sl2[off]);
}
if (sx+n->x+x>x2) x2=sx+n->x+x;
}
screen->add_dirty(x1,sy,x2,sy+mask_height-1);
}
mask_line *make_mask_lines(image *mask, int map_width)
{
mask_line *p=(mask_line *)jmalloc(mask->height()*sizeof(mask_line),"mask_line");
for (int y=0;y<mask->height();y++)
{
// find the start of the run..
uchar *sl=mask->scan_line(y);
int x=0;
while (*sl==0) { sl++; x++; }
p[y].x=x;
// find the length of the run
int size=0;
while (*sl!=0 && x<mask->width()) { sl++; x++; size++; }
p[y].size=size;
// now calculate remap for line
p[y].remap=(ushort *)jmalloc(size*2,"mask remap");
ushort *rem=p[y].remap;
for (x=0;x<size;x++,rem++)
{
if (x<=size/2)
*rem=(int)(sqrt(x/(double)size)*map_width/2.0);
else *rem=(int)(mask->width()-(sqrt((size-x)/(double)size)*map_width/2.0)+mask->width()/2);
}
}
return p;
}
static void draw_vol(image *screen, int x1, int y1, int x2, int y2, int t, int max, int c1, int c2)
{
int dx=x1+t*(x2-x1)/max;
if (t!=0)
screen->bar(x1,y1,dx,y2,c1);
else dx--;
if (dx<x2)
screen->bar(dx+1,y1,x2,y2,c2);
}
static void draw_sfx_vol()
{
draw_vol(volume_window->screen,5,17,34,23,sfx_volume,127,pal->find_closest(255,0,0),
pal->find_closest(90,0,0));
}
static void draw_music_vol()
{
draw_vol(volume_window->screen,5,72,34,78,music_volume,127,pal->find_closest(255,0,0),
pal->find_closest(90,0,0));
}
static void create_volume_window()
{
char *ff="art/frame.spe";
int t=SPEC_IMAGE;
int u_u=cash.reg(ff,"u_u",t,1),
u_d=cash.reg(ff,"u_u",t,1),
u_ua=cash.reg(ff,"u_ua",t,1),
u_da=cash.reg(ff,"u_da",t,1),
d_u=cash.reg(ff,"d_u",t,1),
d_d=cash.reg(ff,"d_u",t,1),
d_ua=cash.reg(ff,"d_ua",t,1),
d_da=cash.reg(ff,"d_da",t,1);
volume_window=eh->new_window(prop->getd("volume_x",xres/2-20),
prop->getd("volume_y",yres/2-50),
41-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT,
101-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM,
new ico_button(10,27,ID_SFX_DOWN,d_u,d_d,d_ua,d_da,
new ico_button(21,27,ID_SFX_UP,u_u,u_d,u_ua,u_da,
new ico_button(10,63,ID_MUSIC_DOWN,d_u,d_d,d_ua,d_da,
new ico_button(21,63,ID_MUSIC_UP,u_u,u_d,u_ua,u_da,
NULL)))));
cash.img(cash.reg(ff,"vcontrol",t,1))->put_image(volume_window->screen,0,0);
draw_music_vol();
draw_sfx_vol();
volume_window->inm->redraw();
eh->grab_focus(volume_window);
}
#define MENU_TICONS 19
int menu_icons[MENU_TICONS*3];
int menu_icons_ids[MENU_TICONS]={ID_START_GAME,ID_VOLUME,ID_NULL,ID_NULL,ID_NULL,ID_NULL,
ID_NULL,ID_NULL,ID_QUIT,ID_NULL,ID_EASY,ID_NULL,
ID_MEDIUM,ID_NULL,ID_HARD,ID_NULL,ID_LIGHT_ON,ID_LIGHT_OFF,
ID_EXTREME };
static jwindow *ico_win;
void save_difficulty()
{
FILE *fp=fopen("hardness.lsp","wb");
if (!fp)
dprintf("Unable to write to file hardness.lsp\n");
else
{
fprintf(fp,"(setf difficulty '");
if (DEFINEDP(l_difficulty))
{
if (symbol_value(l_difficulty)==l_extreme)
fprintf(fp,"extreme)\n");
else if (symbol_value(l_difficulty)==l_hard)
fprintf(fp,"hard)\n");
else if (symbol_value(l_difficulty)==l_easy)
fprintf(fp,"easy)\n");
else
fprintf(fp,"medium)\n");
} else
fprintf(fp,"medium)\n");
fclose(fp);
}
}
void menu_handler(event &ev, jwindow *ico_win)
{
switch (ev.type)
{
case EV_MESSAGE :
{
switch (ev.message.id)
{
case ID_LIGHT_OFF :
{
gamma_correct(pal,1);
} break;
case ID_START_GAME :
{
the_game->load_level(level_file);
the_game->set_state(RUN_STATE);
} break;
case ID_VOLUME :
{ create_volume_window(); } break;
case ID_SFX_UP :
{ if (volume_window)
{
sfx_volume+=16;
if (sfx_volume>127) sfx_volume=127;
draw_sfx_vol();
}
} break;
case ID_SFX_DOWN :
{ if (volume_window)
{
sfx_volume-=16;
if (sfx_volume<0) sfx_volume=0;
draw_sfx_vol();
}
} break;
case ID_MUSIC_UP :
{ if (volume_window)
{
music_volume+=16;
if (music_volume>127) music_volume=127;
draw_music_vol();
}
} break;
case ID_MUSIC_DOWN :
{ if (volume_window)
{
music_volume-=16;
if (music_volume<0) music_volume=0;
draw_music_vol();
}
} break;
case ID_MEDIUM :
{
set_symbol_value(l_difficulty,l_medium);
save_difficulty();
} break;
case ID_HARD :
{
set_symbol_value(l_difficulty,l_hard);
save_difficulty();
} break;
case ID_EXTREME :
{
set_symbol_value(l_difficulty,l_extreme);
save_difficulty();
} break;
case ID_EASY :
{
set_symbol_value(l_difficulty,l_easy);
save_difficulty();
} break;
} break;
} break;
case EV_CLOSE_WINDOW :
{
if (ev.window==volume_window)
{ eh->close_window(volume_window); volume_window=NULL; }
} break;
}
}
void *current_demo=NULL;
void main_menu()
{
image *Earth=cash.img(earth);
image *Emap=cash.img(earth_mask);
char name[20];
ico_button *buts[MENU_TICONS];
long maxx=0,maxy=0;
int i=0;
for (;i<MENU_TICONS;i++)
{
sprintf(name,"icon%04d.pcx",i*3+1);
menu_icons[i*3]=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
sprintf(name,"icon%04d.pcx",i*3+2);
menu_icons[i*3+1]=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
sprintf(name,"icon%04d.pcx",i*3+2);
menu_icons[i*3+2]=cash.reg("art/icons.spe",name,SPEC_IMAGE,1);
long x=WINDOW_FRAME_LEFT+(i%9)*cash.img(menu_icons[0])->width();
long y=WINDOW_FRAME_TOP+(i/9)*cash.img(menu_icons[0])->height();
if (x>maxx) maxx=x;
if (y>maxy) maxy=y;
buts[i]=new ico_button(x,y,menu_icons_ids[i],
menu_icons[i*3],menu_icons[i*3],
menu_icons[i*3+1],menu_icons[i*3+2],NULL);
}
buts[0]->next=buts[1];
int b1,b2,b3,b4;
if (DEFINEDP(symbol_value))
{
if (symbol_value(l_difficulty)==l_extreme)
{ b1=18; b2=10; b3=12; b4=14; }
else if (symbol_value(l_difficulty)==l_hard)
{ b1=14; b2=18; b3=10; b4=12; }
else if (symbol_value(l_difficulty)==l_easy)
{ b1=10; b2=12; b3=14; b4=18; }
else
{ b1=12; b2=14; b3=18; b4=10; }
} else
{ b1=12; b2=14; b3=18; b4=10; }
buts[b1]->next=buts[b2];
buts[b2]->next=buts[b3];
buts[b3]->next=buts[b4];
buts[1]->next=new ico_switch_button(buts[0]->X(),
buts[0]->Y()+cash.img(menu_icons[0])->height()*2,
ID_NULL,
buts[b1],buts[17]);
buts[17]->next=buts[8];
buts[1]->set_xy(buts[0]->X(),
buts[0]->Y()+cash.img(menu_icons[0])->height()*1);
buts[12]->set_xy(buts[0]->X(),
buts[0]->Y()+cash.img(menu_icons[0])->height()*2);
buts[17]->set_xy(buts[0]->X(),
buts[0]->Y()+cash.img(menu_icons[0])->height()*3);
buts[8]->set_xy(buts[0]->X(),
buts[0]->Y()+cash.img(menu_icons[0])->height()*4);
ico_win=eh->new_window(-1,yres/2-80,-1,-1,buts[0],"Menu");
// pmenu *main_pm=new pmenu(0,0,game_sub,screen,eh);
time_marker old_time;
screen->add_dirty(0,0,319,199);
// create sphere map
mask_line *p=make_mask_lines(Emap,Earth->width());
int eoff=0,coff=0;
event ev;
// main_pm->draw(screen,eh,1);
long x=84,y=60;
Cell *v=find_symbol("earth_x");
if (v && DEFINEDP(v)) x=lnumber_value(symbol_value(v));
v=find_symbol("earth_y");
if (v && DEFINEDP(v)) y=lnumber_value(symbol_value(v));
int state=0,stop_menu=0;
time_marker start;
do
{
time_marker new_time;
if (state || new_time.diff_time(&old_time)>0.15)
{
old_time.get_time();
scan_map(screen,x,y,Earth,NULL,p,Emap->height(),eoff,coff);
if (state)
{ eoff+=8; coff+=4; }
else
{
eoff+=2; coff+=1;
}
if (eoff>=320) eoff-=320;
if (coff>=320) coff-=320;
eh->flush_screen();
}
if (eh->event_waiting())
{
eh->get_event(ev);
start.get_time(); // reset time till demo starts up
menu_handler(ev,ico_win);
if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button && ev.mouse_move.x>=x && ev.mouse_move.y>=y &&
ev.mouse_move.x<=x+Emap->width() && ev.mouse_move.y<=y+Emap->height())
{
state=1;
} else if (ev.type==EV_MOUSE_BUTTON && !ev.mouse_button) state=0;
eh->flush_screen();
}
if (new_time.diff_time(&start)>10)
{
if (!current_demo)
{
void *d=make_find_symbol("demos");
if (DEFINEDP(d))
current_demo=symbol_value(d);
}
if (current_demo)
{
if (set_demo_mode(DEMO_PLAY,lstring_value(CAR(current_demo)),eh))
stop_menu=1;
current_demo=CDR(current_demo);
}
}
} while (!stop_menu &&
(ev.type!=EV_MESSAGE || (ev.message.id!=ID_START_GAME && ev.message.id!=ID_QUIT)));
for (i=0;i<MENU_TICONS;i++)
{
ifield *ic=ico_win->inm->unlink(menu_icons_ids[i]);
if (i) delete ic;
else delete buts[i];
}
eh->close_window(ico_win);
for (int xx=0;xx<Emap->height();xx++)
jfree(p[xx].remap);
jfree(p);
if (ev.message.id==ID_QUIT) // propogate the quit message
the_game->end_session();
// delete main_pm;
}
/* pmenu_item *net_sub=new pmenu_item("Multiplayer",
new psub_menu(
new pmenu_item(ID_MODEM, "Modem",-1,
new pmenu_item(ID_TCPIP, "TCP/IP (internet)",-1,
new pmenu_item(ID_IPX, "IPX",-1,
new pmenu_item(ID_SPLIT_SCREEN, "Split screen",-1,
NULL)))),NULL),NULL,200);
pmenu_item *graphics_sub=new pmenu_item("Options",
new psub_menu(
new pmenu_item(ID_KEY_SETUP, "Keyboard",-1,
new pmenu_item(ID_MOUSE_SETUP, "Mouse",-1,
new pmenu_item(CALB_JOY, "Joystick",-1,
new pmenu_item(0, NULL, -1,
new pmenu_item(ID_LIGHT_DETAIL, "Lighting detail",-1,
new pmenu_item(ID_SCREEN_SIZE, "Screen Size",-1,
new pmenu_item(ID_VOLUME, "Volume",-1,
new pmenu_item(ID_SFX_CHANNELS, "Sfx Channels",-1,
NULL)))))))),NULL),net_sub,100);
pmenu_item *game_sub=new pmenu_item("Game",
new psub_menu(
new pmenu_item(ID_NEW_GAME, "New Game",-1,
new pmenu_item(ID_DIFFICULTY,"Difficulty",-1,
new pmenu_item(ID_LOAD_GAME, "Load Game",-1,
new pmenu_item(ID_QUIT, "Quit",-1,NULL)))),NULL),graphics_sub,27);
*/